/**
 * 手写板组件
 * Drawing Canvas Component
 */

class DrawingCanvas {
  constructor(container, options = {}) {
    this.container = typeof container === 'string' ? document.querySelector(container) : container;
    this.options = {
      width: 800,
      height: 600,
      backgroundColor: '#ffffff',
      strokeColor: '#000000',
      strokeWidth: 2,
      maxStrokeWidth: 20,
      minStrokeWidth: 1,
      exportFormat: 'image/webp',
      exportQuality: 0.8,
      maxFileSize: 1024 * 1024, // 1MB
      ...options
    };
    
    this.canvas = null;
    this.ctx = null;
    this.isDrawing = false;
    this.lastX = 0;
    this.lastY = 0;
    this.strokes = []; // 存储所有笔画用于撤销/重做
    this.currentStroke = null;
    this.history = [];
    this.historyIndex = -1;
    this.maxHistory = 50;
    
    this.init();
  }

  /**
   * 初始化手写板
   */
  init() {
    if (!this.container) {
      console.error('Drawing Canvas: Container not found');
      return;
    }

    this.createCanvas();
    this.createToolbar();
    this.bindEvents();
    this.saveToHistory();
  }

  /**
   * 创建画布
   */
  createCanvas() {
    this.container.innerHTML = `
      <div class="drawing-canvas bg-white border border-neutral-200 rounded-lg overflow-hidden">
        <!-- 工具栏 -->
        <div id="drawing-toolbar" class="border-b border-neutral-200 bg-neutral-50 p-3 flex flex-wrap items-center gap-3">
          <!-- 工具栏内容将通过 createToolbar 方法生成 -->
        </div>
        
        <!-- 画布区域 -->
        <div class="canvas-container relative bg-white" style="width: ${this.options.width}px; height: ${this.options.height}px;">
          <canvas 
            id="drawing-canvas"
            width="${this.options.width}"
            height="${this.options.height}"
            class="block cursor-crosshair"
            style="touch-action: none;"
          ></canvas>
          
          <!-- 画布状态提示 -->
          <div class="absolute top-2 right-2 text-xs text-neutral-400 bg-white/80 px-2 py-1 rounded">
            <span id="canvas-status">就绪</span>
          </div>
        </div>
        
        <!-- 底部操作栏 -->
        <div class="border-t border-neutral-200 bg-neutral-50 px-4 py-2 flex items-center justify-between">
          <div class="flex items-center gap-3">
            <button id="undo-btn" class="btn-icon" title="撤销 (Ctrl+Z)">
              <i class="fa fa-undo"></i>
            </button>
            <button id="redo-btn" class="btn-icon" title="重做 (Ctrl+Y)">
              <i class="fa fa-repeat"></i>
            </button>
            <button id="clear-btn" class="btn-icon text-red-500" title="清空画布">
              <i class="fa fa-trash"></i>
            </button>
          </div>
          
          <div class="flex items-center gap-2">
            <button id="save-drawing-btn" class="btn-primary">
              <i class="fa fa-save mr-1"></i>
              保存手写
            </button>
            <button id="insert-drawing-btn" class="btn-success">
              <i class="fa fa-plus mr-1"></i>
              插入到笔记
            </button>
          </div>
        </div>
      </div>
    `;

    this.canvas = this.container.querySelector('#drawing-canvas');
    this.ctx = this.canvas.getContext('2d');
    this.toolbar = this.container.querySelector('#drawing-toolbar');
    
    // 设置画布背景
    this.clearCanvas();
    
    // 设置绘图上下文默认属性
    this.updateDrawingStyle();
  }

  /**
   * 创建工具栏
   */
  createToolbar() {
    this.toolbar.innerHTML = `
      <!-- 笔触工具 -->
      <div class="flex items-center gap-2">
        <label class="text-sm font-medium text-neutral-700">笔触:</label>
        <button id="pen-tool" class="tool-btn active" data-tool="pen" title="钢笔">
          <i class="fa fa-pencil"></i>
        </button>
        <button id="brush-tool" class="tool-btn" data-tool="brush" title="画笔">
          <i class="fa fa-paint-brush"></i>
        </button>
        <button id="eraser-tool" class="tool-btn" data-tool="eraser" title="橡皮擦">
          <i class="fa fa-eraser"></i>
        </button>
      </div>
      
      <div class="w-px h-6 bg-neutral-300"></div>
      
      <!-- 颜色选择 -->
      <div class="flex items-center gap-2">
        <label class="text-sm font-medium text-neutral-700">颜色:</label>
        <div class="flex items-center gap-1">
          <button class="color-btn active" data-color="#000000" style="background-color: #000000" title="黑色"></button>
          <button class="color-btn" data-color="#FF0000" style="background-color: #FF0000" title="红色"></button>
          <button class="color-btn" data-color="#00FF00" style="background-color: #00FF00" title="绿色"></button>
          <button class="color-btn" data-color="#0000FF" style="background-color: #0000FF" title="蓝色"></button>
          <button class="color-btn" data-color="#FFFF00" style="background-color: #FFFF00" title="黄色"></button>
          <button class="color-btn" data-color="#FF00FF" style="background-color: #FF00FF" title="紫色"></button>
          <button class="color-btn" data-color="#00FFFF" style="background-color: #00FFFF" title="青色"></button>
          <input type="color" id="custom-color" class="w-8 h-8 rounded border border-neutral-300 cursor-pointer" value="${this.options.strokeColor}" title="自定义颜色">
        </div>
      </div>
      
      <div class="w-px h-6 bg-neutral-300"></div>
      
      <!-- 笔触粗细 -->
      <div class="flex items-center gap-2">
        <label class="text-sm font-medium text-neutral-700">粗细:</label>
        <input 
          type="range" 
          id="stroke-width" 
          min="${this.options.minStrokeWidth}" 
          max="${this.options.maxStrokeWidth}" 
          value="${this.options.strokeWidth}"
          class="w-20"
        >
        <span id="stroke-width-display" class="text-sm text-neutral-600 min-w-[2rem]">${this.options.strokeWidth}px</span>
      </div>
      
      <div class="w-px h-6 bg-neutral-300"></div>
      
      <!-- 透明度 -->
      <div class="flex items-center gap-2">
        <label class="text-sm font-medium text-neutral-700">透明度:</label>
        <input 
          type="range" 
          id="stroke-opacity" 
          min="0.1" 
          max="1" 
          step="0.1"
          value="1"
          class="w-20"
        >
        <span id="opacity-display" class="text-sm text-neutral-600 min-w-[3rem]">100%</span>
      </div>
    `;
  }

  /**
   * 绑定事件
   */
  bindEvents() {
    // 画布绘图事件
    this.canvas.addEventListener('mousedown', (e) => this.startDrawing(e));
    this.canvas.addEventListener('mousemove', (e) => this.draw(e));
    this.canvas.addEventListener('mouseup', () => this.stopDrawing());
    this.canvas.addEventListener('mouseout', () => this.stopDrawing());
    
    // 触摸事件支持
    this.canvas.addEventListener('touchstart', (e) => {
      e.preventDefault();
      const touch = e.touches[0];
      const mouseEvent = new MouseEvent('mousedown', {
        clientX: touch.clientX,
        clientY: touch.clientY
      });
      this.canvas.dispatchEvent(mouseEvent);
    });
    
    this.canvas.addEventListener('touchmove', (e) => {
      e.preventDefault();
      const touch = e.touches[0];
      const mouseEvent = new MouseEvent('mousemove', {
        clientX: touch.clientX,
        clientY: touch.clientY
      });
      this.canvas.dispatchEvent(mouseEvent);
    });
    
    this.canvas.addEventListener('touchend', (e) => {
      e.preventDefault();
      const mouseEvent = new MouseEvent('mouseup', {});
      this.canvas.dispatchEvent(mouseEvent);
    });
    
    // 工具栏事件
    this.bindToolbarEvents();
    
    // 操作按钮事件
    this.bindActionEvents();
    
    // 键盘快捷键
    this.bindKeyboardEvents();
  }

  /**
   * 绑定工具栏事件
   */
  bindToolbarEvents() {
    // 工具选择
    this.toolbar.querySelectorAll('.tool-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        this.toolbar.querySelectorAll('.tool-btn').forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        this.currentTool = btn.dataset.tool;
        this.updateDrawingStyle();
      });
    });
    
    // 颜色选择
    this.toolbar.querySelectorAll('.color-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        this.toolbar.querySelectorAll('.color-btn').forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        this.options.strokeColor = btn.dataset.color;
        this.updateDrawingStyle();
      });
    });
    
    // 自定义颜色
    const customColor = this.toolbar.querySelector('#custom-color');
    customColor.addEventListener('change', (e) => {
      this.toolbar.querySelectorAll('.color-btn').forEach(b => b.classList.remove('active'));
      this.options.strokeColor = e.target.value;
      this.updateDrawingStyle();
    });
    
    // 笔触粗细
    const strokeWidth = this.toolbar.querySelector('#stroke-width');
    const strokeWidthDisplay = this.toolbar.querySelector('#stroke-width-display');
    strokeWidth.addEventListener('input', (e) => {
      this.options.strokeWidth = parseInt(e.target.value);
      strokeWidthDisplay.textContent = `${this.options.strokeWidth}px`;
      this.updateDrawingStyle();
    });
    
    // 透明度
    const strokeOpacity = this.toolbar.querySelector('#stroke-opacity');
    const opacityDisplay = this.toolbar.querySelector('#opacity-display');
    strokeOpacity.addEventListener('input', (e) => {
      this.options.strokeOpacity = parseFloat(e.target.value);
      opacityDisplay.textContent = `${Math.round(this.options.strokeOpacity * 100)}%`;
      this.updateDrawingStyle();
    });
  }

  /**
   * 绑定操作按钮事件
   */
  bindActionEvents() {
    // 撤销
    this.container.querySelector('#undo-btn').addEventListener('click', () => {
      this.undo();
    });
    
    // 重做
    this.container.querySelector('#redo-btn').addEventListener('click', () => {
      this.redo();
    });
    
    // 清空
    this.container.querySelector('#clear-btn').addEventListener('click', () => {
      if (confirm('确定要清空画布吗？此操作不可撤销。')) {
        this.clearCanvas();
        this.saveToHistory();
      }
    });
    
    // 保存手写
    this.container.querySelector('#save-drawing-btn').addEventListener('click', () => {
      this.saveDrawing();
    });
    
    // 插入到笔记
    this.container.querySelector('#insert-drawing-btn').addEventListener('click', () => {
      this.insertToEditor();
    });
  }

  /**
   * 绑定键盘事件
   */
  bindKeyboardEvents() {
    document.addEventListener('keydown', (e) => {
      if (e.ctrlKey || e.metaKey) {
        switch (e.key.toLowerCase()) {
          case 'z':
            e.preventDefault();
            if (e.shiftKey) {
              this.redo();
            } else {
              this.undo();
            }
            break;
          case 'y':
            e.preventDefault();
            this.redo();
            break;
        }
      }
    });
  }

  /**
   * 开始绘制
   */
  startDrawing(e) {
    this.isDrawing = true;
    const rect = this.canvas.getBoundingClientRect();
    this.lastX = e.clientX - rect.left;
    this.lastY = e.clientY - rect.top;
    
    // 开始新的笔画
    this.currentStroke = {
      tool: this.currentTool || 'pen',
      color: this.options.strokeColor,
      width: this.options.strokeWidth,
      opacity: this.options.strokeOpacity || 1,
      points: [{ x: this.lastX, y: this.lastY }]
    };
    
    this.updateStatus('绘制中...');
  }

  /**
   * 绘制
   */
  draw(e) {
    if (!this.isDrawing) return;
    
    const rect = this.canvas.getBoundingClientRect();
    const currentX = e.clientX - rect.left;
    const currentY = e.clientY - rect.top;
    
    // 添加点到当前笔画
    this.currentStroke.points.push({ x: currentX, y: currentY });
    
    // 绘制线条
    this.ctx.beginPath();
    this.ctx.moveTo(this.lastX, this.lastY);
    this.ctx.lineTo(currentX, currentY);
    this.ctx.stroke();
    
    this.lastX = currentX;
    this.lastY = currentY;
  }

  /**
   * 停止绘制
   */
  stopDrawing() {
    if (!this.isDrawing) return;
    
    this.isDrawing = false;
    
    // 保存当前笔画
    if (this.currentStroke && this.currentStroke.points.length > 1) {
      this.strokes.push(this.currentStroke);
      this.saveToHistory();
    }
    
    this.currentStroke = null;
    this.updateStatus('就绪');
  }

  /**
   * 更新绘图样式
   */
  updateDrawingStyle() {
    if (!this.ctx) return;
    
    const tool = this.currentTool || 'pen';
    
    switch (tool) {
      case 'pen':
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.strokeStyle = this.options.strokeColor;
        this.ctx.lineWidth = this.options.strokeWidth;
        this.ctx.lineCap = 'round';
        this.ctx.lineJoin = 'round';
        break;
        
      case 'brush':
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.strokeStyle = this.options.strokeColor;
        this.ctx.lineWidth = this.options.strokeWidth * 1.5; // 画笔稍粗
        this.ctx.lineCap = 'round';
        this.ctx.lineJoin = 'round';
        break;
        
      case 'eraser':
        this.ctx.globalCompositeOperation = 'destination-out';
        this.ctx.lineWidth = this.options.strokeWidth * 2; // 橡皮擦更粗
        this.ctx.lineCap = 'round';
        this.ctx.lineJoin = 'round';
        break;
    }
    
    // 设置透明度
    this.ctx.globalAlpha = this.options.strokeOpacity || 1;
  }

  /**
   * 清空画布
   */
  clearCanvas() {
    this.ctx.fillStyle = this.options.backgroundColor;
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    this.strokes = [];
  }

  /**
   * 重绘画布
   */
  redrawCanvas() {
    this.clearCanvas();
    
    this.strokes.forEach(stroke => {
      this.drawStroke(stroke);
    });
  }

  /**
   * 绘制单个笔画
   */
  drawStroke(stroke) {
    if (stroke.points.length < 2) return;
    
    const oldCompositeOperation = this.ctx.globalCompositeOperation;
    const oldStrokeStyle = this.ctx.strokeStyle;
    const oldLineWidth = this.ctx.lineWidth;
    const oldLineCap = this.ctx.lineCap;
    const oldLineJoin = this.ctx.lineJoin;
    const oldGlobalAlpha = this.ctx.globalAlpha;
    
    // 设置笔画样式
    switch (stroke.tool) {
      case 'pen':
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.strokeStyle = stroke.color;
        this.ctx.lineWidth = stroke.width;
        break;
        
      case 'brush':
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.strokeStyle = stroke.color;
        this.ctx.lineWidth = stroke.width * 1.5;
        break;
        
      case 'eraser':
        this.ctx.globalCompositeOperation = 'destination-out';
        this.ctx.lineWidth = stroke.width * 2;
        break;
    }
    
    this.ctx.lineCap = 'round';
    this.ctx.lineJoin = 'round';
    this.ctx.globalAlpha = stroke.opacity || 1;
    
    // 绘制路径
    this.ctx.beginPath();
    this.ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
    
    for (let i = 1; i < stroke.points.length; i++) {
      this.ctx.lineTo(stroke.points[i].x, stroke.points[i].y);
    }
    
    this.ctx.stroke();
    
    // 恢复原始样式
    this.ctx.globalCompositeOperation = oldCompositeOperation;
    this.ctx.strokeStyle = oldStrokeStyle;
    this.ctx.lineWidth = oldLineWidth;
    this.ctx.lineCap = oldLineCap;
    this.ctx.lineJoin = oldLineJoin;
    this.ctx.globalAlpha = oldGlobalAlpha;
  }

  /**
   * 保存到历史记录
   */
  saveToHistory() {
    const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
    
    // 删除当前位置之后的历史记录
    this.history = this.history.slice(0, this.historyIndex + 1);
    
    // 添加新的历史记录
    this.history.push(imageData);
    
    // 限制历史记录数量
    if (this.history.length > this.maxHistory) {
      this.history.shift();
    } else {
      this.historyIndex++;
    }
  }

  /**
   * 撤销
   */
  undo() {
    if (this.historyIndex > 0) {
      this.historyIndex--;
      const imageData = this.history[this.historyIndex];
      this.ctx.putImageData(imageData, 0, 0);
      this.updateStatus('已撤销');
    }
  }

  /**
   * 重做
   */
  redo() {
    if (this.historyIndex < this.history.length - 1) {
      this.historyIndex++;
      const imageData = this.history[this.historyIndex];
      this.ctx.putImageData(imageData, 0, 0);
      this.updateStatus('已重做');
    }
  }

  /**
   * 保存手写内容
   */
  async saveDrawing() {
    try {
      this.updateStatus('保存中...');
      
      const blob = await this.exportAsBlob();
      const url = URL.createObjectURL(blob);
      
      // 创建下载链接
      const a = document.createElement('a');
      a.href = url;
      a.download = `手写_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.webp`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      
      URL.revokeObjectURL(url);
      
      this.updateStatus('保存成功');
      
      // 触发保存事件
      this.dispatchEvent('save', { blob, url });
      
    } catch (error) {
      console.error('保存手写失败:', error);
      this.updateStatus('保存失败');
    }
  }

  /**
   * 插入到编辑器
   */
  async insertToEditor() {
    try {
      this.updateStatus('插入中...');
      
      const blob = await this.exportAsBlob();
      
      // 触发插入事件
      this.dispatchEvent('insert', { blob });
      
      this.updateStatus('插入成功');
      
    } catch (error) {
      console.error('插入手写失败:', error);
      this.updateStatus('插入失败');
    }
  }

  /**
   * 导出为Blob
   */
  async exportAsBlob() {
    return new Promise((resolve, reject) => {
      this.canvas.toBlob((blob) => {
        if (blob) {
          // 检查文件大小
          if (blob.size > this.options.maxFileSize) {
            reject(new Error(`文件大小超出限制 (最大 ${Math.round(this.options.maxFileSize / 1024)}KB)`));
            return;
          }
          resolve(blob);
        } else {
          reject(new Error('导出失败'));
        }
      }, this.options.exportFormat, this.options.exportQuality);
    });
  }

  /**
   * 导出为DataURL
   */
  exportAsDataURL() {
    return this.canvas.toDataURL(this.options.exportFormat, this.options.exportQuality);
  }

  /**
   * 加载图片到画布
   */
  loadImage(src) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => {
        this.clearCanvas();
        this.ctx.drawImage(img, 0, 0, this.canvas.width, this.canvas.height);
        this.saveToHistory();
        resolve();
      };
      img.onerror = reject;
      img.src = src;
    });
  }

  /**
   * 更新状态
   */
  updateStatus(status) {
    const statusEl = this.container.querySelector('#canvas-status');
    if (statusEl) {
      statusEl.textContent = status;
    }
  }

  /**
   * 分发事件
   */
  dispatchEvent(eventName, data) {
    const event = new CustomEvent(`drawingCanvas:${eventName}`, {
      detail: data,
      bubbles: true,
      cancelable: true
    });
    
    this.container.dispatchEvent(event);
    
    // 如果有回调函数，调用它
    const callbackName = `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
    if (typeof this.options[callbackName] === 'function') {
      this.options[callbackName](data);
    }
  }

  /**
   * 获取画布内容是否为空
   */
  isEmpty() {
    const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
    const data = imageData.data;
    
    // 检查是否所有像素都是背景色
    for (let i = 0; i < data.length; i += 4) {
      const r = data[i];
      const g = data[i + 1];
      const b = data[i + 2];
      const a = data[i + 3];
      
      // 如果发现非背景色像素，说明有内容
      if (a > 0 && (r !== 255 || g !== 255 || b !== 255)) {
        return false;
      }
    }
    
    return true;
  }

  /**
   * 销毁组件
   */
  destroy() {
    // 移除事件监听器
    // 注意：这里简化处理，实际应该保存引用并移除
    
    this.container.innerHTML = '';
  }
}

// 导出手写板组件
window.DrawingCanvas = DrawingCanvas;